package middleware

import (
	"context"
	"time"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/guid"
)

const CtxLogIDKey = "X-Log-Id"

// LogIDMiddleware 日志ID中间件
func LogIDMiddleware(r *ghttp.Request) {
	start := time.Now()
	ctx := r.Context()

	// 获取或生成LogID
	logID := r.Header.Get("X-Log-Id")
	if logID == "" {
		logID = "log-" + guid.S()
	}

	// 设置上下文LogID
	newCtx := context.WithValue(ctx, CtxLogIDKey, logID)
	r.SetCtx(newCtx)

	// 响应头添加LogID
	r.Response.Header().Set("X-Log-Id", logID)

	// 处理后续请求
	r.Middleware.Next()

	// 记录请求日志
	cost := time.Since(start)
	g.Log().Printf(r.Context(),
		"[REQ] log_id:%s | method:%s | path:%s | ip:%s | status:%d | cost:%s | query_string:%s|| param:%s| user_agent:%s | header:%s",
		logID,
		r.Method,
		r.Request.URL.RequestURI(),
		r.GetClientIp(),
		r.Response.Status,
		cost.String(),
		r.GetQueryMap(),
		r.GetBodyString(),
		r.UserAgent(),
		r.Header,
	)

	// 3. 执行后续处理（控制器逻辑）
	r.Middleware.Next()
	// 5. 计算耗时（当前时间 - 开始时间），转换为毫秒
	costMs := int64(time.Since(start) / time.Millisecond)

	// 4. 记录响应日志（包含同一log_id）
	respLog := g.Map{
		"log_id":   logID,
		"status":   r.Response.Status,                            // 响应状态码
		"cost_ms":  costMs,                                       // 耗时（毫秒）
		"response": r.Response.BufferString(),                    // 响应数据（注意：大响应需过滤）
		"end_time": time.Now().Format("2006-01-02 15:04:05.000"), // 记录结束时间
	}
	g.Log().Info(ctx, "RESPONSE:", respLog)
}
